package org.puppet.game.control;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.puppet.game.Controller;

public class Director {

	private Map<Integer, List<Controller>> controllers;
	private Set<Controller> waitUnreg;

	public Director() {
		controllers = Collections.synchronizedMap(new HashMap<Integer, List<Controller>>());
		waitUnreg = new HashSet<Controller>();
	}

	public void reg(Controller controller) {
		int[] eks = controller.lookEvent();

		for (int i = 0; i < eks.length; i++) {
			Integer ek = new Integer(eks[i]);
			if (!controllers.containsKey(ek)) {
				controllers.put(ek, new ArrayList<Controller>());
			}
			if (!controllers.get(ek).contains(controller)) {
				controllers.get(ek).add(controller);
			}
		}
	}

	private void trueUnreg(Controller controller) {
		for (List<Controller> cs : controllers.values()) {
			cs.remove(controller);
		}
	}

	public void unreg(Controller controller) {
		waitUnreg.add(controller);
	}

	public boolean broadcast(Integer eventId, Object e) {
		boolean result = true;

		if (waitUnreg.size() > 0) {
			for (Controller wc : waitUnreg) {
				trueUnreg(wc);
			}
			waitUnreg.clear();
		}
		
		List<Controller> cs = controllers.get(eventId);
		if (null != cs && cs.size() > 0) {
			for (int i = 0, len = cs.size(); i < len; i++) {
				Controller c = cs.get(i);
				result = c.action(eventId, e);
				if (!result)
					return false;
			}
		}

		return result;
	}

	public Map<Integer, List<Controller>> getControllers() {
		return controllers;
	}
}
